home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
076-100
/
093
/
dme
/
command.c
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
9KB
|
385 lines
/*
* COMMAND.C
*
* (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
*
* 'c single character (typing)
* `string' string of characters w/ embedded `' allowed!
*
* name arg arg command name. The arguments are interpreted as strings
* for the command.
*
* Any string arguments not part of a command are considered to be typed
* text.
*/
#include "defs.h"
extern char *breakout();
short ComLineMode;
char Abortcommand;
typedef struct {
char *name; /* command name */
short args; /* # of arguments */
short sl; /* 1 if stays within bounds of the current line */
int (*func)(); /* function */
} COMM;
extern int do_map(), do_unmap(), do_up(), do_down(), do_left(), do_right(),
do_return(), do_bs(), do_del(), do_esc(), do_downadd(),
do_lastcolumn(), do_firstcolumn(), do_edit(), do_tab(),
do_backtab(), do_save(), do_saveas(), do_deline(), do_insline(),
do_top(), do_bottom(), do_source(), do_firstnb(),
do_quit(), do_find(), do_page(), do_savetabs(),
do_split(), do_goto(), do_screentop(), do_screenbottom(),
do_join(), do_repeat(), do_tabstop(), do_insertmode(),
do_block(), do_bdelete(), do_bcopy(), do_bmove(), do_bsave(),
do_wleft(), do_wright(), do_remeol(), do_savemap(),
do_toggle(), do_if(), do_tlate(), do_bsource(),
do_findr(), do_findstr(), do_newwindow(),
do_windowparm(), do_resize(), do_margin(), do_wordwrap(),
do_reformat(), do_execute();
extern int do_iconify(), do_tomouse();
/*
* WLEFT/WRIGHT will check command line mode themselves, and thus can
* be marked sl=1 even though they can change the line number.
*
* No more than 255 commands may exist unless you change the type of hindex[]
*
* Command names MUST be sorted by their first character
*/
unsigned char hindex[26]; /* alpha hash into table */
COMM Comm[] = {
"back", 0, 1, do_bs,
"backtab", 0, 1, do_backtab,
"bcopy", 0, 0, do_bcopy,
"bdelete", 0, 0, do_bdelete,
"block", 0, 0, do_block, /* checks com name for mode */
"bmove", 0, 0, do_bmove,
"bottom", 0, 0, do_bottom,
"bs", 0, 1, do_bs,
"bsave", 1, 0, do_bsave,
"bsource", 0, 0, do_bsource,
"del", 0, 1, do_del,
"deline", 0, 0, do_deline,
"down", 0, 0, do_down,
"downadd", 0, 0, do_downadd,
"esc", 0, 1, do_esc,
"escimm", 1, 0, do_esc,
"execute", 1, 0, do_execute,
"find", 1, 0, do_find, /* checks com name for mode */
"findr", 2, 0, do_findr, /* checks com name for mode */
"findstr", 1, 1, do_findstr, /* checks com name for mode */
"first", 0, 1, do_firstcolumn,
"firstnb", 0, 1, do_firstnb,
"goto", 1, 0, do_goto,
"height", 1, 1, do_windowparm,
"iconify", 0, 0, do_iconify,
"if", 2, 0, do_if,
"ifelse", 3, 0, do_if,
"insertmode", 1, 1, do_insertmode,
"insfile", 1, 0, do_edit,
"insline", 0, 0, do_insline,
"join", 0, 0, do_join,
"last", 0, 1, do_lastcolumn,
"left", 0, 1, do_left,
"leftedge", 1, 1, do_windowparm,
"map", 2, 0, do_map,
"margin", 1, 1, do_margin,
"newfile", 1, 0, do_edit, /* checks com name for mode */
"newwindow", 0, 0, do_newwindow,
"next", 0, 0, do_find,
"nextr", 0, 0, do_findr,
"pagedown", 0, 0, do_page,
"pageset", 1, 0, do_page,
"pageup", 0, 0, do_page,
"prev", 0, 0, do_find,
"prevr", 0, 0, do_findr,
"quit", 0, 0, do_quit,
"reformat", 0, 0, do_reformat,
"remeol", 0, 1, do_remeol,
"repeat", 2, 1, do_repeat,
"repstr", 1, 1, do_findstr,
"resettoggle", 1, 1, do_toggle,
"resize", 2, 0, do_resize,
"return", 0, 1, do_return, /* special meaning in command line mode */
"right", 0, 1, do_right,
"saveas", 1, 0, do_saveas,
"savemap", 1, 0, do_savemap, /* checks com name for mode */
"saveold", 0, 0, do_save,
"savesmap", 1, 0, do_savemap,
"savetabs", 1, 0, do_savetabs,
"screenbottom", 0, 0, do_screenbottom,
"screentop", 0, 0, do_screentop,
"settoggle", 1, 1, do_toggle,
"source", 1, 0, do_source,
"split", 0, 0, do_split,
"tab", 0, 1, do_tab,
"tabstop", 1, 1, do_tabstop,
"tlate", 1, 0, do_tlate,
"toggle", 1, 1, do_toggle,
"tomouse", 0, 0, do_tomouse,
"top", 0, 0, do_top,
"topedge", 1, 1, do_windowparm,
"unblock", 0, 0, do_block,
"unmap", 1, 0, do_unmap,
"up", 0, 0, do_up,
"while", 2, 0, do_if,
"width", 1, 1, do_windowparm,
"wleft", 0, 1, do_wleft,
"wordwrap", 1, 1, do_wordwrap,
"wright", 0, 1, do_wright,
NULL, 0, 0, NULL
};
init_command()
{
register short hi;
register COMM *comm;
hi = sizeof(Comm)/sizeof(Comm[0]) - 2;
comm = Comm + hi;
while (hi >= 0) {
hindex[comm->name[0] - 'a'] = hi;
--hi;
--comm;
}
}
do_command(str)
char *str;
{
register char *arg;
char quoted;
register short i, j;
static int level;
if (++level > 20) {
title("Recursion Too Deep!");
--level;
return(0);
}
while (arg = breakout(&str, "ed)) {
if (quoted) {
text_write(arg);
continue;
}
for (i = 0; arg[i]; ++i) {
if (arg[i] >= 'A' && arg[i] <= 'Z')
arg[i] += 'a' - 'A';
}
if (arg[0] >= 'a' && arg[0] <= 'z') {
register COMM *comm = &Comm[hindex[arg[0]-'a']];
for (; comm->name && comm->name[0] == arg[0]; ++comm) {
if (strcmp(arg, comm->name) == 0) {
av[0] = (u_char *)comm->name;
for (j = 1; j <= comm->args; ++j) {
av[j] = (u_char *)breakout(&str, "ed);
if (!av[j]) {
title("Bad argument");
--level;
return(0);
}
}
if (comm->sl || !ComLineMode)
(*comm->func)(-1);
if (Abortcommand)
goto fail;
goto loop;
}
}
}
/* Command not found, check for macro */
{
char *str;
int ret;
str = keyspectomacro(arg);
if (str) {
str = (char *)strcpy(malloc(strlen(str)+1), str);
ret = do_command(str);
free(str);
if (ret)
goto loop;
goto fail;
}
}
title("Unknown Command");
fail:
--level;
return(0);
loop:
;
}
--level;
return(1);
}
do_source()
{
char buf[256];
long fi;
register short i;
if (fi = xopen(av[1], "r", 256)) {
while (xgets(fi, buf, 255)) {
for (i = 0; buf[i]; ++i) {
if (buf[i] == 9)
buf[i] = ' ';
}
do_command(buf);
}
xclose(fi);
} else {
if (av[0])
title("File not found");
}
}
do_quit()
{
extern char Quitflag;
Quitflag = 1;
}
do_execute()
{
Execute(av[1], 0, 0);
}
/*
* repeat X command
*
* Since repeat takes up 512+ stack, it should not be nested more than
* twice.
*
* (if X is not a number it can be abbr. with 2 chars)
*
* X = N -number of repeats
* line -current line # (lines begin at 1)
* lbot -#lines to the bottom, inc. current
* cleft -column # (columns begin at 0)
* (thus is also chars to the left)
* cright-#chars to eol, including current char
* tr -#char positions to get to next tab stop
* tl -#char positions to get to next backtab stop
*/
#define SC(a,b) ((a)<<8|(b))
do_repeat()
{
u_char *ptr = av[1];
char buf1[256];
char buf2[256];
unsigned long n;
breakreset();
strcpy(buf1, av[2]);
switch((ptr[0]<<8)+ptr[1]) {
case SC('l','i'):
n = text_lineno();
break;
case SC('l','b'):
n = text_lines() - text_lineno() + 1;
break;
case SC('c','l'):
n = text_colno();
break;
case SC('c','r'):
n = text_cols() - text_colno();
break;
case SC('t','r'):
n = text_tabsize()-(text_colno() % text_tabsize());
break;
case SC('t','l'):
n = text_colno() % text_tabsize();
if (n == 0)
n = text_tabsize();
break;
default:
n = atoi(av[1]);
break;
}
while (n > 0) {
strcpy(buf2, buf1);
if (do_command(buf2) == 0 || breakcheck()) {
Abortcommand = 1;
break;
}
--n;
}
}
char *
breakout(ptr, quoted)
register char **ptr;
char *quoted;
{
register char *str = *ptr;
register char *base = str;
*quoted = 0;
while (*str == ' ')
++str;
if (!*str)
return(NULL);
if (*str == '\'') {
if (str[1]) {
*quoted = 1;
base = str + 1;
if (str[2])
++str;
*str = '\0';
*ptr = str;
return(base);
}
return(NULL);
}
if (*str == '`') {
short count = 1;
base = ++str;
while (*str && count) {
if (*str == '`')
++count;
if (*str == '\'')
--count;
++str;
}
if (count == 0) {
--str;
*quoted = 1;
*str = '\0';
*ptr = str + 1;
return(base);
}
}
base = str;
while (*str && *str != ' ')
++str;
if (*str) {
*str = '\0';
*ptr = str + 1;
return(base);
}
*ptr = str;
return(base);
}